-- UIAwakeDungeon
-- Create by chendh
-- 觉醒地牢列表

require "game/ui/form/dungeon/UIEnterDungeon"

-- UIAwakeDungeon继承自Layer
UIAwakeDungeon = class("UIAwakeDungeon", function()
    return cc.Layer:create();
end);

function UIAwakeDungeon.create()
    return UIAwakeDungeon.new();
end

-- 构造函数
function UIAwakeDungeon:ctor()
    self:setName("UIAwakeDungeon");

    self.showFinished = nil;

    -- 初始化
    local node = cc.CSLoader:createNode("layout/main/SubMapList.csb");
    self:addChild(node);
    self.node = node;

    -- 设置标题样式
    local titleLabel = findChildByName(node, "TOP/title_bg/text");
    TextStyleM.setOutlineStyle(titleLabel, 1, TextStyleM.TEXT_OUTLINE_COLOR, true);
    titleLabel:setString(getLocStr("awake_dungeon_title"));
    TextStyleM.setArtWordTitleStyle(titleLabel);

    -- 适配
    self:resize(self);

    self:initData();

    self:initGrid();

    -- 绘制界面
    self:redraw(true);

    -- 注册事件处理回调函数
    self:registerEventCallback();

    -- 注册点击事件
    self:registerTouchEvent();
end

-- 注册事件回调
function UIAwakeDungeon:registerEventCallback()
    -- 注册获得焦点的回调
    EventMgr.register("UIAwakeDungeon", event.FOCUS_CHANGED, function(para)
        if para["get"] == "UIAwakeDungeon" then
            local btNode = findChildByName(self.node, "BT");
            btNode:setVisible(true);

            UIMgr:getCurrentScene().topMenu:show(TOPMENU_FRAME_TREE, TOPMENU_FRAME_LIFE);
        elseif para["lose"] == "UIAwakeDungeon" then
            local btNode = findChildByName(self.node, "BT");
            btNode:setVisible(false);
        end
    end);

    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(ev)
        if ev == "exit" then
            EventMgr.removeAll("UIAwakeDungeon");

            if UIMgr:getCurrentScene():isOpen("UIGainItemPath") then
                local uiForm = UIMgr:getCurrentScene():getFormByName("UIGainItemPath");
                uiForm:redraw();
            else
                if UIMgr.getCurrentScene().mainMap then
                    UIMgr.getCurrentScene().mainMap:resumeEffect();

                    if DungeonM.isInDungeon() then
                        if UIMgr.getCurrentScene().topMenu then
                            UIMgr.getCurrentScene().topMenu:checkPauseState();
                        end
                    end
                end
            end
        elseif ev == "enter" then
            if UIMgr.getCurrentScene().mainMap then
                UIMgr.getCurrentScene().mainMap:stopEffect();
            end

            local function showTop()
                if UIMgr.getCurrentScene().topMenu then
                    UIMgr.getCurrentScene().topMenu:checkPauseState();
                end
            end
            performWithDelay(self, showTop, 0.01);
        end
    end)
end

-- 注册点击响应
function UIAwakeDungeon:registerTouchEvent()
    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            if self.showFinished then
                self.showFinished = nil;
                self:initData();
                self:initGrid();
                self:redraw(true);
            else
                -- 关闭当前界面
                AudioM.playFx("button_return");
                UIMgr.getCurrentScene():removeFormByName("UIAwakeDungeon");
            end
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    -- 神庙介绍按钮
    local btnIntroduce = findChildByName(self.node, "BT/btn_dungeon");
    local function onIntroduceClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 显示神庙介绍界面
            showActivityTip(getLocStr("awake_dungeon_desc_title"), getLocStr("awake_dungeon_desc") .. "\n" .. getLocStr("awake_dungeon_desc_tip"));
        end
    end
    local hint = btnIntroduce:getChildByName("hint");
    hint:setVisible(false);
    btnIntroduce:addTouchEventListener(onIntroduceClick);
    TextStyleM.setTextStyle(btnIntroduce, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnIntroduce:setTitleText(getLocStr("btn_text_awake_dungeon_intro"));

    -- 已完成按钮
    local btnFinished = findChildByName(self.node, "BT/leaderboard");
    local function onFinishedClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");

            self.showFinished = true;
            self:initData();
            self:initGrid();
            self:redraw(true);
        end
    end
    btnFinished:addTouchEventListener(onFinishedClick);
    TextStyleM.setTextStyle(btnFinished, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnFinished:setTitleText(getLocStr("btn_text_finished"));
end

-- 初始化数据
function UIAwakeDungeon:initData()
    local list = {};
    local petList = AwakeM.getAllOpenedAwake();

    for _, petId in ipairs(petList) do
        if self.showFinished then
            -- 显示已完成觉醒地牢试炼的冈布奥
            if AwakeM.isFinishAwakeDungeon(petId) then
                table.insert(list, petId);
            end
        else
            -- 显示已获得且未成觉醒地牢试炼的冈布奥
            local pet = PetM.getMyPet(petId);

            if pet and not AwakeM.isFinishAwakeDungeon(petId) then
                table.insert(list, petId);
            end
        end
    end

    local function sortAwakeDungeon(petId1, petId2)
        local can1 = AwakeM.canAwakeDungeonTrial(petId1) == true;
        local can2 = AwakeM.canAwakeDungeonTrial(petId2) == true;
        if can1 ~= can2 then
            return can1;
        else
            return petId1 < petId2;
        end
    end
    table.sort(list, sortAwakeDungeon);

    self.awakePetList = list;
end

-- 初始化地牢列表
function UIAwakeDungeon:initGrid()
    local scrollView = findChildByName(self.node, "TOP/scrollview");
    self.scrollView = scrollView;
    self.scrollView.rows = {};
    self.scrollView:removeAllChildren();

    local itemNode = cc.CSLoader:createNode("layout/main/SubMapItem.csb");

    -- 获取觉醒冈布奥列表
    local totalNum      = #self.awakePetList;

    local pageRowNum    = 5;
    local maxColNum     = 1;
    local leftWGap      = 30;
    local topHGap       = 5;
    local bottomHGap    = 10;
    local wGap          = 20;
    local hGap          = 15;
    local iconWidth     = 550;
    local iconHeight    = 110;

    -------------------------------------------------------------------------------
    -- 初始化滚动容器内的单元格（仅针对竖向滚动容器）
    -- @param windowNode    界面节点
    -- @param scrollNode    容器节点
    -- @param itemNode      单元格的节点
    -- @param totalNum      单元格总数
    -- @param pageRowNum    单页可以显示下的行数
    -- @param maxColNum     最大列数
    -- @param wGap          单元格间距(横向) 这里作为最小值使用
    -- @param hGap          单元格间距(纵向)
    -- @param iconWidth     单元格宽度
    -- @param iconHeight    单元格高度
    -- @param topHGap       上方留白
    -- @param bottomHGap    下方留白
    -- @param leftWGap      左右留白  这里作为最小值使用
    -- @param touchEvent    点击事件注册函数
    initScrollGridsVertical(self, scrollView, itemNode, totalNum, pageRowNum, maxColNum, wGap, hGap, iconWidth, iconHeight, topHGap, bottomHGap, leftWGap, self.registerDungeonItemTouchEvent)
end

-- 地牢点击响应
function UIAwakeDungeon:registerDungeonItemTouchEvent(node)
    local bgBtn  = findChildByName(node, "btn_bg");
    local areaBg  = findChildByName(node, "area_bg");
    local function onClick(sender, eventType)
        if eventType == ccui.TouchEventType.began then
            -- 1.变小
            local downTime  = 0.25/2;
            local scaleDown = cc.ScaleTo:create(downTime, 0.9);
            node:runAction(scaleDown);
        elseif eventType == ccui.TouchEventType.ended then
            -- 2.变大
            local downTime  = 0.25/2;
            local scaleUp = cc.ScaleTo:create(downTime, 1);
            node:runAction(scaleUp);
        elseif eventType == ccui.TouchEventType.canceled then
            -- 3.变大
            local downTime  = 0.25/2;
            local scaleUp = cc.ScaleTo:create(downTime, 1);
            node:runAction(scaleUp);
        end

        -- 点击时的回调
        if eventType == ccui.TouchEventType.ended then
            local petId = node.petId;
            local dungeonId = AwakeM.query(petId, "dungeon");

            -- 如果未通关且条件不满足，则弹出提示后返回
            if not AwakeM.isFinishAwakeDungeon(petId) and
                AwakeM.canAwakeDungeonTrial(petId) ~= true then
                alert(string.format(getLocStr("cannot_awake_dungeon"), PetM.query(petId, "name")));
                return;
            end

            if DungeonM.isPause() then
                -- 暂离状态(提示状态)
                alert(getLocStr("cant_restart_dungeon"));
                return;
            end

            -- 如果体力不足
            local lifeCost = DungeonAreaM.calcDungeonLifeCost(dungeonId);
            if ME.user.dbase:query("life", 0) < lifeCost then
                confirmBuyLife();
                return;
            end

            -- 如果该地牢限制了出战的冈布奥，那么检测一下
            local limitPet = DungeonAreaM.query(dungeonId, "limit_active_pet");

            if type(limitPet) == "number" and limitPet ~= ME.user.dbase:query("active_pet", 0) then
                -- "限XXX冈布奥出战"
                alert(string.format(getLocStr("dungeon_limit_active_pet"), PetM.query(limitPet, "name")));
                return;
            end

            -- 进入地牢
            if UIMgr:getCurrentScene():isOpen("UIEnterDungeon") then
                UIMgr:getCurrentScene():removeForm("UIEnterDungeon");
            end
            local uiEnterDungeon = UIEnterDungeon.create(dungeonId);
            UIMgr.getCurrentScene():addForm(uiEnterDungeon);
            AudioM.playFx("ui_open1");
        end
    end

    bgBtn:addTouchEventListener(onClick);
    areaBg:addTouchEventListener(onClick);
end

-- 清空所有的觉醒地牢格
function UIAwakeDungeon:clearAllGrid()
    self.scrollView:removeAllChildren();
end

-- 绘制界面
function UIAwakeDungeon:redraw(showEffect)
    local node = self.node;

    -- 按钮是否显示的控制
    local btnIntroduce = findChildByName(self.node, "BT/btn_dungeon");
    local btnFinished = findChildByName(node, "BT/leaderboard");
    -- 如果显示的是已完成的觉醒试炼，则不显示介绍和已完成按钮
    if self.showFinished then
        btnIntroduce:setVisible(false);
        btnFinished:setVisible(false);
    else
        btnIntroduce:setVisible(true);

        -- 有已完成的试炼则显示"已完成"按钮，否则隐藏
        if AwakeM.calcFinishedAwakeDungeonNum() > 0 then
            btnFinished:setVisible(true);
        else
            btnFinished:setVisible(false);
        end
    end

    -- 绘制列表
    local itemList  = {}
    local itemCount = #self.awakePetList;
    local index     = 0;

    if not self.awakePetList or itemCount == 0 then
        cclog("收集觉醒冈布奥列表信息失败。");
        self:clearAllGrid();
        return;
    end

    for index = 1, itemCount do
        -- 获取格子
        local child = self.scrollView:getChildByName("item" .. index);
        if child == nil then
            break;
        end

        -- 插入格子列表，用以播放飞入效果
        table.insert(itemList, child);

        local petId = self.awakePetList[index];
        child.petId = petId;
        self:redrawItem(child, petId);
    end

    -- 如果需要播放飞入效果，则调用公用接口进行飞入
    if showEffect then
        commonScrollItemFlyIn(itemList);
    end

end

-- 绘制觉醒地牢格子
function  UIAwakeDungeon:redrawItem(node, petId)
    local dungeonId = AwakeM.query(petId, "dungeon");
    -- 名称
    local name = DungeonAreaM.query(dungeonId, "name");

    -- 关卡背景图片
    local areaBg  = findChildByName(node, "area_bg");
    local bgIndex = DungeonAreaM.query(dungeonId, "area_bg");
    areaBg:loadTexture(getSubAreaBgPath(bgIndex));

    local nameLabel = findChildByName(node, "name");
    local layerLabel = findChildByName(node, "layer");
    local bgImg  = findChildByName(node, "btn_bg");
    local areaImg  = findChildByName(node, "area_bg");
    local lifeIcon = findChildByName(node, "life_icon");
    local lightImage = findChildByName(node, "light");
    local diamondImage = findChildByName(node, "diamond_bg");

    lifeIcon:removeAllChildren();
    lifeIcon:setVisible(false);
    lightImage:stopAllActions();
    lightImage:setVisible(false);
    diamondImage:stopAllActions();
    diamondImage:setScale(1);
    diamondImage:setVisible(false);
    setGrayMode(diamondImage, false);
    setGrayMode(bgImg, false);
    setGrayMode(areaImg, false);

    -- 觉醒地牢的名称和附加描述
    TextStyleM.setTextStyle(nameLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_LIGHT_YELLOW, true, -3, 1.2, nil, nil, nil, true);
    TextStyleM.setTextStyle(layerLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_LIGHT_BLUE, true, -2, 1.2, nil, nil, nil, true);
    nameLabel:setString(name);

    if AwakeM.isFinishAwakeDungeon(petId) then
        -- 已完成了觉醒地牢试炼
        layerLabel:setString(getLocStr("awake_dungeon_finished"));

        -- 绘制消耗的体力
        local requireLife = DungeonAreaM.calcDungeonLifeCost(dungeonId);
        local lifeLayer = createLifeLayer(requireLife, "right", -0.4);
        lifeIcon:addChild(lifeLayer);
        lifeIcon:setVisible(true);
    elseif AwakeM.canAwakeDungeonTrial(petId) == true then
        -- 条件满足，可以参与地牢试炼
        layerLabel:setString(string.format(getLocStr("awake_dungeon_can"), PetM.query(petId, "short_name")));

        -- 绘制消耗的体力
        local requireLife = DungeonAreaM.calcDungeonLifeCost(dungeonId);
        local lifeLayer = createLifeLayer(requireLife, "right", -0.4);
        lifeIcon:addChild(lifeLayer);
        lifeIcon:setVisible(true);
    else
        -- 条件不满足，无法参与地牢试炼
        layerLabel:setString(getLocStr("awake_dungeon_cannot"));

        -- 背景框灰化
        setGrayMode(bgImg, true);
        setGrayMode(areaImg, true);

        -- 载入冈布奥图标
        diamondImage:loadTexture(getHeroIconPath(PetM.getDefaultIcon(petId)));
        diamondImage:setScale(0.8);
        diamondImage:setVisible(true);
        setGrayMode(diamondImage, true);
    end
end

-- 界面适配
function UIAwakeDungeon:resize()
    local w = AlignM.frameSize.width;
    local h = AlignM.frameSize.height;

    local scale = w / DESIGN_WIDTH;

    -- 设置scroll的新视口高度
    local scrollview = findChildByName(self.node, "TOP/scrollview");
    local scrollViewSize = scrollview:getContentSize();

    local height = (h / scale) - 420;
    scrollview:setContentSize(scrollViewSize.width, height);

    -- 保存窗口适配后的原始高度
    self.originScrollviewHeight = height;

    local node = self.node;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");
    AlignM.fitToScreen(node, "bg2");

    -- TOP置于顶部中间并缩放至合适大小
    AlignM.alignToTopCenter(node, "TOP");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end
